Skip to content

Add streaming ORDER BY queries#4800

Open
tvaron3 wants to merge 4 commits into
Azure:mainfrom
tvaron3:tvaron3-plan-query-aggregations
Open

Add streaming ORDER BY queries#4800
tvaron3 wants to merge 4 commits into
Azure:mainfrom
tvaron3:tvaron3-plan-query-aggregations

Conversation

@tvaron3

@tvaron3 tvaron3 commented Jul 17, 2026

Copy link
Copy Markdown
Member

Summary

  • add resumable cross-partition streaming ORDER BY execution
  • preserve exact Cosmos value and RID ordering across pages and partition splits
  • add a source-attributed cross-SDK scenario catalog and emulator/live coverage

Testing

  • cargo test -p azure_data_cosmos_driver --all-features
  • cargo clippy -p azure_data_cosmos_driver --all-features --all-targets -- -D warnings
  • cargo clippy -p azure_data_cosmos --all-features --all-targets -- -D warnings
  • PR cSpell check
  • live Gateway ORDER BY query-plan parity
  • live numeric/string ASC/DESC and mixed-direction resume across a real 1-to-2 partition split

Fixes #4756

Implement resumable cross-partition ORDER BY merging with exact Cosmos value ordering, durable continuation state, and split-safe recovery. Add cross-SDK scenario coverage, emulator validation, and live split tests.\n\nFixes Azure#4756\n\nCo-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>\nCopilot-Session: 80371d09-63a0-4ebc-8bfc-6af45c217151
@github-actions github-actions Bot added the Cosmos The azure_cosmos crate label Jul 17, 2026
tvaron3 added 2 commits July 17, 2026 11:34
Replace the draft pull request placeholders with the upstream PR number.\n\nCo-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>\nCopilot-Session: 80371d09-63a0-4ebc-8bfc-6af45c217151
Resolve planner and Cosmos status-code conflicts while preserving upstream query-range normalization and streaming ORDER BY support.\n\nCo-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>\nCopilot-Session: 80371d09-63a0-4ebc-8bfc-6af45c217151

@analogrelay analogrelay left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some initial comments. Looking like a good start though! I still need to go through the actual merge processes so not ready to approve quite yet.

Future node types (e.g., streaming ORDER BY, hybrid search) may require partial parsing of item bodies. The backend query plan can rewrite the query to use a standardized envelope (promoting ordering keys to top-level fields and demoting the raw user document to a `payload` field). This varied-shape pattern must be considered in the overall design direction, but does not need to be accommodated in the current implementation.
`StreamingOrderedMerge` (cross-partition `ORDER BY`) is the first node type that parses item bodies: the backend query plan's `rewrittenQuery` reshapes each per-partition result into a standardized envelope (`{"_rid": ..., "orderByItems": [...], "payload": ...}` — sort keys promoted to top-level fields, the raw user document demoted to `payload`). The pipeline parses just enough of this envelope to compare rows and emit `payload` — see `driver::dataflow::order_by` (the value/comparator/resume-value model) and `driver::dataflow::query_response` (envelope parsing and response reassembly). Hybrid search, if implemented, would need the same pattern for its own envelope shape.

Resume for streaming `ORDER BY` is per-range and topology-change-safe. Each still-active range persists its last-emitted key tuple and envelope `_rid`. On resume — including after a partition split or merge — a **scalar** boundary is turned into a key-only seek filter (`... > boundary OR ... = boundary`) that returns every row at or after the boundary, including the full-key tie run; a `_rid` predicate is deliberately not part of this SQL, since `_rid` compares as an ordinal base64 string in Cosmos SQL, not the backend's numeric document order. The already-emitted prefix of that tie run is instead discarded client-side by a numeric `_rid` comparison (see `models::resource_id::compare_document_rids`), so resume stays exact per row and splits/clips to sub-ranges without any positional row count. An **array/object** (complex) sort key is persisted only as a bounded 128-bit hash, so it cannot form a seek filter; it resumes by a whole-range positional re-scan, which is valid only while the range's topology is unchanged — a resume that would cross a split is rejected with a typed error (`CosmosStatus::CLIENT_STREAMING_MERGE_COMPLEX_BOUNDARY_TOPOLOGY_CHANGE`) rather than risk silently dropping rows.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An array/object (complex) sort key is persisted only as a bounded 128-bit hash, so it cannot form a seek filter;

Is that what other SDKs do? Just want to make sure we're not introducing an arbitrary limitation here that other SDKs don't have. In general, I think array/object sort keys are an anti-pattern anyway, so I'm not really that worried.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.NET also stores array/object resume values as a bounded 128-bit low/high DistinctHash and sends them through the structured resumeFilter understood by the backend. Java explicitly does not support continuation tokens for array/object ORDER BY keys. I switched Rust to the .NET resumeFilter shape and ported the backend/.NET DistinctHash exactly, with the published .NET baseline vectors as tests. The spec now calls out the peer behavior.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although in java this is something we do not support.

Comment thread sdk/cosmos/azure_data_cosmos_driver/src/driver/dataflow/order_by.rs Outdated
Comment thread sdk/cosmos/azure_data_cosmos_driver/src/driver/dataflow/order_by.rs
Comment thread sdk/cosmos/azure_data_cosmos_driver/src/driver/dataflow/order_by.rs Outdated
Comment thread sdk/cosmos/azure_data_cosmos_driver/src/driver/dataflow/order_by.rs Outdated
Comment thread sdk/cosmos/azure_data_cosmos_driver/src/driver/dataflow/order_by.rs Outdated
Comment thread sdk/cosmos/azure_data_cosmos_driver/src/driver/dataflow/order_by.rs Outdated
Comment thread sdk/cosmos/azure_data_cosmos_driver/src/driver/dataflow/planner.rs Outdated
Align resume handling with the .NET structured resume filter and DistinctHash, add JOIN skip-count support, preserve split-node abstraction, and update emulator coverage for the now-supported query path.\n\nCo-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>\nCopilot-Session: 80371d09-63a0-4ebc-8bfc-6af45c217151
@tvaron3
tvaron3 marked this pull request as ready for review July 23, 2026 06:21
@tvaron3
tvaron3 requested a review from a team as a code owner July 23, 2026 06:21
Copilot AI review requested due to automatic review settings July 23, 2026 06:21
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
2 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@tvaron3

tvaron3 commented Jul 23, 2026

Copy link
Copy Markdown
Member Author

/azp run rust - cosmos - weekly

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds resumable, cross-partition streaming ORDER BY execution to the Cosmos driver, including deterministic ordering and partition-split recovery.

Changes:

  • Implements ordered merging, continuation snapshots, resume filtering, and RID tie-breaking.
  • Adds emulator query rewriting and complex-value hashing support.
  • Adds scenario, integration, emulator, and live split coverage.

Reviewed changes

Copilot reviewed 30 out of 31 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
sdk/cosmos/.cspell.json Adds new technical terms.
sdk/cosmos/azure_data_cosmos/CHANGELOG.md Announces ORDER BY support.
sdk/cosmos/azure_data_cosmos/tests/emulator_tests/cosmos_query.rs Updates query expectations.
sdk/cosmos/azure_data_cosmos/tests/in_memory_emulator.rs Registers emulator coverage.
sdk/cosmos/azure_data_cosmos/tests/split_tests/cosmos_query_order_by_split.rs Adds live split-resume tests.
sdk/cosmos/azure_data_cosmos/tests/split_tests/mod.rs Registers split tests.
sdk/cosmos/azure_data_cosmos_driver/CHANGELOG.md Documents driver behavior.
sdk/cosmos/azure_data_cosmos_driver/Cargo.toml Updates test dependencies.
sdk/cosmos/azure_data_cosmos_driver/docs/FEED_OPERATIONS_REQS.md Updates query requirements.
sdk/cosmos/azure_data_cosmos_driver/src/driver/cosmos_driver.rs Advertises ORDER BY capabilities.
sdk/cosmos/azure_data_cosmos_driver/src/driver/dataflow/distinct_hash.rs Implements Cosmos-compatible hashing.
sdk/cosmos/azure_data_cosmos_driver/src/driver/dataflow/integration_tests/mod.rs Registers integration tests.
sdk/cosmos/azure_data_cosmos_driver/src/driver/dataflow/integration_tests/order_by_resume.rs Tests resume behavior.
sdk/cosmos/azure_data_cosmos_driver/src/driver/dataflow/mocks.rs Extends dataflow test mocks.
sdk/cosmos/azure_data_cosmos_driver/src/driver/dataflow/mod.rs Registers ORDER BY modules.
sdk/cosmos/azure_data_cosmos_driver/src/driver/dataflow/order_by.rs Implements ordering and boundaries.
sdk/cosmos/azure_data_cosmos_driver/src/driver/dataflow/planner.rs Builds ordered pipelines.
sdk/cosmos/azure_data_cosmos_driver/src/driver/dataflow/query_response.rs Processes rewritten envelopes.
sdk/cosmos/azure_data_cosmos_driver/src/driver/dataflow/snapshot.rs Adds durable ordered state.
sdk/cosmos/azure_data_cosmos_driver/src/driver/dataflow/streaming_ordered_merge.rs Implements streaming merge and repair.
sdk/cosmos/azure_data_cosmos_driver/src/error/cosmos_status.rs Extends status handling.
sdk/cosmos/azure_data_cosmos_driver/src/in_memory_emulator/operations.rs Synthesizes ORDER BY plans.
sdk/cosmos/azure_data_cosmos_driver/src/in_memory_emulator/rid.rs Supports deterministic emulator RIDs.
sdk/cosmos/azure_data_cosmos_driver/src/models/mod.rs Registers model support.
sdk/cosmos/azure_data_cosmos_driver/src/models/resource_id.rs Parses and compares resource IDs.
sdk/cosmos/azure_data_cosmos_driver/src/query/eval/mod.rs Evaluates rewritten queries.
sdk/cosmos/azure_data_cosmos_driver/src/query/mod.rs Exposes query internals.
sdk/cosmos/azure_data_cosmos_driver/tests/fixtures/streaming_order_by_scenarios.json Catalogs cross-SDK scenarios.
sdk/cosmos/azure_data_cosmos_driver/tests/in_memory_emulator_tests/mod.rs Registers ORDER BY tests.
sdk/cosmos/azure_data_cosmos_driver/tests/in_memory_emulator_tests/order_by.rs Tests emulator ordering.
sdk/cosmos/azure_data_cosmos_driver/tests/streaming_order_by_scenario_catalog.rs Validates scenario coverage.
Comments suppressed due to low confidence (2)

sdk/cosmos/azure_data_cosmos_driver/src/driver/dataflow/order_by.rs:345

  • Objects have the same Cosmos ordering rule as arrays: their DistinctHash values are compared with the UInt128 binary comparer. Sorting keys and values structurally produces a different order from the service, so a cross-partition merge can emit object-keyed rows out of order. Reuse the same complex-hash comparator for this branch.
            (Self::Object(a), Self::Object(b)) => {
                let mut a_sorted: Vec<&(String, OrderByItem)> = a.iter().collect();
                let mut b_sorted: Vec<&(String, OrderByItem)> = b.iter().collect();
                a_sorted.sort_by(|x, y| x.0.cmp(&y.0));
                b_sorted.sort_by(|x, y| x.0.cmp(&y.0));

sdk/cosmos/azure_data_cosmos_driver/src/driver/dataflow/order_by.rs:682

  • The resume-boundary string comparison must use the same ordinal UTF-16 relation as the merge comparator and Cosmos. Using Rust's scalar/UTF-8 order here can misclassify non-BMP boundaries after a split, causing rows to be skipped or replayed.
        (OrderByItem::String(a), OrderByResumeValue::String { value }) => {
            ColumnCmp::Ordered(a.as_str().cmp(value.as_str()))
        }

Comment thread sdk/cosmos/azure_data_cosmos_driver/src/driver/dataflow/order_by.rs
Comment thread sdk/cosmos/azure_data_cosmos_driver/src/driver/dataflow/order_by.rs
@analogrelay analogrelay moved this from In Progress to Needs Attention in CosmosDB Rust SDK and Driver Jul 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Cosmos The azure_cosmos crate

Projects

Status: Needs Attention

Development

Successfully merging this pull request may close these issues.

Support streaming ORDER BY queries

3 participants